package com.zx.idc.backend.gui.common.base;

import com.zx.idc.backend.gui.common.BasicBaseApi;
import com.zx.idc.common.exception.GlobalException;

import java.util.Optional;
import java.util.function.Function;

/**
 * 基本的依赖注入 api 接口
 * 注意：该接口中的 {@link #getService()} 最好进行覆盖，如果你继承了 {@link BasicBaseApi}，那么会自动注入
 *
 * @param <Service> 服务类接口对象
 * @param <Entity>  实现类
 * @author rxliuli
 */
public interface BaseDependencyInjectionApi<Service, Entity> {
    /**
     * 获取一个 Service，由子类实现
     * 实现这个方法可以更快的获取到 Service 以提高响应速度
     *
     * @return 服务类实现对象
     */
    default Optional<Service> getService() {
        return Optional.empty();
    }

    /**
     * 使用借贷模式使用服务类
     *
     * @param interfaceClazz API 接口的类
     * @param fn             自定义的方法
     * @param <T>            返回值类型
     * @return 自定义的方法的返回值
     * @throws GlobalException 如果找不到 Service 实现，则可能会抛出全局异常
     */
    default <T> T using(Class<?> interfaceClazz, Function<Service, T> fn) {
        //noinspection unchecked
        final Service service = getService()
            .orElseGet(() -> (Service) BaseApiUtil.getGenericClassService(this.getClass(), interfaceClazz)
                .orElseThrow(() -> new GlobalException("继承 " + interfaceClazz.getName() + " 请务必配置泛型参数")));
        return fn.apply(service);
    }
}
